import java.net.InetAddress;
import java.rmi.Naming;
import java.rmi.RemoteException;
import java.rmi.registry.LocateRegistry;
import java.rmi.registry.Registry;
import java.rmi.server.UnicastRemoteObject;
import java.util.HashMap;
import java.util.Map;


public class Server extends UnicastRemoteObject implements Server_itf {
	
	private static final long serialVersionUID = 1L;
	private Map<Integer, ServerObject> objects;
	private Map<String, Integer> names;
	
	private int new_id = 0;

	public Server() throws RemoteException {
		super();
		objects = new HashMap<Integer, ServerObject>();
		names = new HashMap<String, Integer>();
	}

	public int lookup(String name) throws RemoteException {
		Integer i = names.get(name);
		return (i!=null)?i:-1;
	}
	
	public String getClassName(int id) {
		return objects.get(id).obj.getClass().getName();
	}

	public void register(String name, int id) throws RemoteException {
		names.put(name, id);
		System.out.println(name+" registered in the server with id: "+id);
	}

	public int create(Object o) throws RemoteException {
		int id = new_id++;
		try {
			ServerObject so = new ServerObject(o, id);
			objects.put(id, so);
		} catch (Exception e) {
			e.printStackTrace();
		}
		return id;
	}

	public synchronized Object lock_read(int id, Client_itf client) throws RemoteException {
		ServerObject so = objects.get(id);
		return so.lock_read(client);
	}
	
	public synchronized Object lock_write(int id, Client_itf client) throws RemoteException {
		ServerObject so = objects.get(id);
		return so.lock_write(client);
	}
	
	public static void main(String args[]) {
		try {
			LocateRegistry.createRegistry(Registry.REGISTRY_PORT);
			String URL = "//"+InetAddress.getLocalHost().getHostName()+":"+Registry.REGISTRY_PORT+"/server";
			Server_itf server = new Server();
			Naming.bind(URL, server);
			System.out.println("Server launched");
		} catch (Exception e) {
			System.err.println("Server already launched");
			e.printStackTrace();
			System.exit(1);
		}
	}
}
